/* Copyright (c) 2023, Arm Limited and Contributors. All rights reserved.
 * SPDX-License-Identifier: Apache-2.0
 */

#ifndef IOT_BLUETOOTH_HCI_H_
#define IOT_BLUETOOTH_HCI_H_

#ifdef __cplusplus
extern "C" {
#endif

#include "stdbool.h"

#define IOT_HCI_PACKET_TYPE_NONE 0x00
#define IOT_HCI_PACKET_TYPE_CMD  0x01
#define IOT_HCI_PACKET_TYPE_ACL  0x02
#define IOT_HCI_PACKET_TYPE_SCO  0x03
#define IOT_HCI_PACKET_TYPE_EVT  0x04

/**
 * The HCI packet wrapper. Used to transport HCI data from host to controller.
 *
 * Porters note:
 * To accommodate resource constraint hosts the wrapper allows two ways of passing the packet.
 * One is where the packet is separate from the type and the pointer points to data directly, the other is
 * where the type is the first byte in the packet buffer. In both cases type is also present in the 'type' field.
 * The controller implementation must handle both cases.
 */
typedef struct iot_hci_message {
    /** Buffer containing the HCI packet. */
    const uint8_t *packet;
    /** The size of the HCI packet. */
    uint16_t packet_size;
    /** One byte identifier of HCI packet type (e.g.: ACL, EVT, CMD etc.) as defined by the bluetooth spec */
    uint8_t type;
    /** True if the packet starts with the type byte. */
    bool type_included_in_packet;
} iot_hci_message_t;

/**
 * Callback function type for iot_hci_transport_init. Called by the controller to send data to host.
 *
 * @param data        Buffer containing the packet. Caller retains ownership of the memory.
 *                    May contain a partial HCI message and the host is responsible for accumulating the full packet.
 * @param data_length Size of the buffer.
 *
 * @return            0 on success.
 */
typedef int32_t (*iot_hci_host_rx_callback)(const uint8_t *data, size_t data_length);

/**
 * Initialise the controller side driver.
 * Called by the host. Implemented by controller.
 *
 * @param callback  The function to be called by the controller upon receiving data.
 *
 * @return          0 on success.
 */
int32_t iotHciTransportInit(iot_hci_host_rx_callback callback);

/**
 * Send an HCI packet from the host to the controller. Packet must be a complete hci message.
 * Called by host. Implemented by controller.
 *
 * @param message The HCI packet to send. Caller retains memory ownership.
 *
 * @return        0 on success.
 */
int32_t iotHciSendToController(const iot_hci_message_t *message);

#ifdef __cplusplus
}
#endif

#endif /* IOT_BLUETOOTH_HCI_H_ */
